﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using Store.Web.Models;
using Store.Web.PushNotifications;

namespace Store.Web.Services
{
    public class OrderService
    {
        #region Private Fields
        
        private readonly string _connectionString;

        #endregion

        #region Ctors

        public OrderService(string connectionString)
        {
            _connectionString = connectionString;
        }

        #endregion

        #region Public Methods

        public List<Order> GetOrders(int number)
        {
            if (number <= 0)
            {
                return GetOrders();
            }
            else
            {
                using (var storeDbContext = new StoreDbContext(_connectionString))
                {
                    return storeDbContext.Orders
                        .OrderByDescending(o => o.ModificationDate)
                        .Include(c => c.Products)
                        .Include(c => c.Customer)
                        .Take(number)
                        .ToList();
                }
            }
        }

        public List<Order> GetOrders()
        {
            using (var storeDbContext = new StoreDbContext(_connectionString))
            {
                return storeDbContext.Orders
                    .OrderByDescending(o => o.ModificationDate)
                    .Include(c => c.Products)
                    .Include(c => c.Customer)
                    .ToList();
            }
        }

        public List<Order> GetCommands(int customerId, int number)
        {
            if (number <= 0)
            {
                return GetCommands(customerId);
            }
            else
            {
                using (var storeDbContext = new StoreDbContext(_connectionString))
                {
                    var orders = storeDbContext.Orders
                                            .OrderByDescending(o => o.ModificationDate)
                                            .Include(c => c.Products)
                                            .Include(c => c.Customer)
                                            .Where(c => c.CustomerId == customerId)
                                            .Take(number)
                                            .ToList();

                    return orders;
                }
            }
        }

        public List<Order> GetCommands(int customerId)
        {
            using (var storeDbContext = new StoreDbContext(_connectionString))
            {
                return storeDbContext.Orders
                    .OrderByDescending(o => o.ModificationDate)
                    .Include(c => c.Products)
                    .Include(c => c.Customer)
                    .Where(c => c.CustomerId == customerId)
                    .ToList();
            }
        }

        public Order GetOrder(int id)
        {
            using (var storeDbContext = new StoreDbContext(_connectionString))
            {
                return storeDbContext.Orders
                    .Include(c => c.Products)
                    .Include(c => c.ShipAddress)
                    .FirstOrDefault(c => c.Id == id);
            }
        }

        public void SubmitCommand(Order order)
        {
            using (var storeDbContext = new StoreDbContext(_connectionString))
            {
                order.Customer = null;
                order.State = 1;
                order.CreationDate = DateTime.Now;
                order.ModificationDate = order.CreationDate;
                storeDbContext.Entry<Order>(order).State = System.Data.EntityState.Added;
                storeDbContext.SaveChanges();
            }
        }

        public void UpdateOrderState(int orderId, int state)
        {
            using (var storeDbContext = new StoreDbContext(_connectionString))
            {
                var command = storeDbContext.Orders.FirstOrDefault(c => c.Id == orderId);
                if (command != null)
                {
                    command.ModificationDate = DateTime.Now;
                    command.State = state;
                }

                storeDbContext.SaveChanges();

                if (state == (int)OrderStates.Sent
                    && storeDbContext.PushSubscriptions.Any(p => p.CustomerId == command.CustomerId))
                {
                    string pushUrl = storeDbContext.PushSubscriptions.First(p => p.CustomerId == command.CustomerId).Url;

                    ToastNotification toastNotification = new ToastNotification();
                    toastNotification.Title = "MyStore";
                    toastNotification.Subtitle = string.Format("Une commande est en cours de livraison", command.Id);
                    toastNotification.Param = string.Format("/Views/OrderDetailsPage.xaml?orderId={0}", command.Id);

                    PushNotificationsHelper.SendToastNotification(toastNotification, pushUrl);
                }
            }
        }

        public int GetOrderState(int orderId)
        {
            using (var storeDbContext = new StoreDbContext(_connectionString))
            {
                return storeDbContext.Orders
                    .Where(c => c.Id == orderId)
                    .Select(o => o.State)
                    .FirstOrDefault();
            }
        }

        #endregion
    }
}